ARTeam Tutorial

UnUPX of any UPXed Program in 15 Easy Steps


Information A simple tecnique for unpacking any UPXed program, even if it has been modified. 10 steps easy to follow without bunch of theory.
Target Atomic Time Synchnonizer
Available http://www.lmhsoft.com/timesync/
Tools OllyDbg 1.10, CommandBar 3.0, PeiD, OllyDump, ImportREC
Protection Program Compression
level Beginners
Category Unpacking Apps
Author &8~) Shub-Nigurrath June 2004


1. Introduction


Hi all, today's problem is quite easy, what we want to learn is how to unpack any UPXed program with an easy to follow procedure that will work for any program that has been packed with UPX. UPX is one of the most simple executable packer, so don't expect the whole word to be so simple! ^__^
Just facts! I think for a newbie will be useful, but not only, also for other experienced people which are used to unpack UPX program only through automatic tools!

The procedure is quite general and works also on modified UPXed programs. As a proof we will apply it to Atomic Time Synchronizer, which has been packed with UPX and then modified so as to not seem UPX. We will go up to unpacking it and further in cracking it, because the target once unpacked is very easy to defeat.

All the available tutorials are filled with theory about unpacking and so on, we don't want to bother you doing this, the only thing we need is the OEP concept (Original Entry Point). Given the original application, just developed from its author, its entry point (the address of the first instruction to be executed, stored in the PE header) is what we call the EP.

The compression process attaches a loader in the beginning of the program, compress the real program and change the EP to the first instruction of the Loader. Then there's a new EP, the EP of the Loader.

Then viceversa, when running the compressed application, at the end of the decompression process, the loader has unpacked the original application in memory and passes the control to it. The first instruction executed then is the same of the unpacked original program, that's our OEP!

So, summing up, every packer needs to unpack the wrapped program in memory, and this works in the following way : A (small) chunk of code is decrypted and placed on the right position in memory by the loader. This process continues until the entire program is unpacked. Next, the loader jumps to the entrypoint of the original program (before it was packed). At this moment, the program is fully unpacked and ready to be dumped from memory to disk :)
 



2. Target's modifications


Any compressor like UPX is recognisable by the Loader's code, which is always the same. Some applications nevertheless modifies this loader so as it cannot be recognised by automatic tools. It's the case of our target.

Let's see the original program PE header Sections and the same sections of the unpacked and repacked program (the unpacked and repacked program is taken directly from the end of this tutorial ^__^)

The repacked program looks like a normal UPX program, while the original has some differences.


Original Program Section Table.


Repacked Program Section Table.

Let's see it in other words, a direct comparison of the two headers of the original still packed program and of the same unpacked and then repacked program with UPX.


Click on the image to see in full size.
On the left there's the repacked app (which looks like a normal UPX),
on the right there's the original app which has some differences..

As you can see the names has been changed from the authors. So, how can we understand that the target is an UPX target? Simple, use PEiD (http://peid.has.it) and use Deep Scan to see which is the compression program used for this baby.


Well no problem, the UPX Loader is still here and can be approached.

Our method starts from a simple consideration. Look the export table of the packed program, there are essentially only these exports from the Kernel32.dll

LoadLibraryA
GetProcAddress
ExitProcess

LoadLibraryA is a very interesting API (or or GetProcessAddress or also GetModuleHandleA, which is just called before LoadLibraryA) for our scope!

Well it's time to open OllyDbg!



3. 15 golden steps


Well enough with theory, just follow these steps!

1. Launch the process in Olly CTRL-F2

2. BP on LoadLibraryA or GetModuleHandleA using the CommandBar's command line.

3. Press F9 to continue up to the first call of LoadLibraryA

4. You land into the kernel32, press "Execute Till Return" and return to the target process

5. The API has been called from a cycle of repeated conditional jumps. Look how the cycle is done (it's always the same with UPX): there are two exit conditions, one an op-code before the other, well the first instruction which is anyway executed is PUSHAD at 536EEA, just below there's the jump to the OEP.

Picture above simply is a composition of OllyDbg screen captures, the jump at the OEP is at 5366EEB. The LoadLibrary was called form the CALL at 536EBE.

6. Go to the jump we identified and press F2 to set a breakpoint then press F9 (as in figure above). Note that you should also stop other times into LoadLibraryA, simply disable that breakpoint if you haven't done yet, it's useless now.

7. Now you are in the situation of the picture above. Press F7 (or F8 it's the same)

8. Stop at the jmp destination address, the OEP! You should have something like below.

9. Dump the process using OllyDump (for example). Note that OllyDump already sets the OEP to the EIP value less the offset, but in case use this simple formula
EP = OEP - base = 004DEC1C - 00400000 = DEC1C (in our case).

Remember that the values in the PE header are always file offsets and not addresses.

10. Open ImportRec and attach to the running process opened in Olly meanwhile (remember to leave OllyDbg open).

11. Write the OEP you found before in the low part of the interface

12. Press "IAT Autosearch" then "Get Imports"


Below the steps you need to do and in which order


13. You should see a table of found imports, with several "YES" beside each one (there shouldn't be "NO").

14. Press FixDump on ImportRec and select the previously saved Dumped file (at step 9)

15. You're gone, now you can run the target process or start patching it.


 



4. Conclusion


A BIG thanks goes to Peroquin and all ARTeam members
and all the other from who I have learnt so much as well as the crew on exetools & other places..
This tute would not have been possible without their hard work
and willingness to pass the knowledge on to others.

I hope someone may find this tut useful

Best Wishes

(.|.)
 ).( (¯`·._.·[¯¨´*·~-.¸¸,.-~*´¨
&8~) Ŝħůβ¬Ňïĝµŕřāŧħ ₪ ¯¨´*·~-.¸¸,.-~*´¨]·._.·´¯)
( v )
 \|/